package com.earl.eatbao.service.impl;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.earl.eatbao.commons.dao.BaseRepsitoty;
import com.earl.eatbao.commons.service.BaseServiceImpl;
import com.earl.eatbao.dao.eatbao.AddressDao;
import com.earl.eatbao.dao.eatbao.GoodsDao;
import com.earl.eatbao.dao.eatbao.OrderDetailDao;
import com.earl.eatbao.dao.eatbao.OrdersDao;
import com.earl.eatbao.domain.eatbao.Address;
import com.earl.eatbao.domain.eatbao.Comment;
import com.earl.eatbao.domain.eatbao.GoodsVo;
import com.earl.eatbao.domain.eatbao.OrderDetail;
import com.earl.eatbao.domain.eatbao.Orders;
import com.earl.eatbao.exception.DomainSecurityException;
import com.earl.eatbao.service.AddressService;
import com.earl.eatbao.service.OrderDetailService;
import com.earl.eatbao.service.OrdersService;
import com.earl.eatbao.util.PayChargeUtil;
import com.pingplusplus.exception.APIConnectionException;
import com.pingplusplus.exception.APIException;
import com.pingplusplus.exception.AuthenticationException;
import com.pingplusplus.exception.ChannelException;
import com.pingplusplus.exception.InvalidRequestException;
import com.pingplusplus.model.Charge;

/**
 * @version:1.0
 * @author: MissYou
 * @date : 8:58
 * @desc: 订单业务逻辑处理
 */
@Service
public class OrdersServiceImpl extends BaseServiceImpl<Orders, Long> implements OrdersService {

    // desc:日志logger
    private static final Logger logger = LoggerFactory.getLogger(OrdersServiceImpl.class);

    @Autowired
    private OrdersDao ordersDao;

    @Autowired
    private OrderDetailDao orderDetailDao;
    
    @Autowired
    private AddressDao addressDao;
    
    @Autowired
    private GoodsDao goodsDao;
    
    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private AddressService addressService;

    public OrdersServiceImpl(){
        System.out.println("dodo");
    }

    @Override
    protected BaseRepsitoty<Orders, Long> getDao() {
        return ordersDao;
    }

    @Override
    public List<Orders> findShopAllOrders(Long shopUserId) {
        logger.info("<====== 进入findShopAllOrders:方法,{[shopUserId] :" + shopUserId + " } ====");
        logger.info("==== 退出findShopAllOrders方法 返回值类型:{List<Orders>: } =======>");
        return ordersDao.findByShopUserIdAndIsDeleteFalse(shopUserId);
    }

    @Override
    public Boolean placeOrder(Orders orders, List<GoodsVo> goods, Long addressId) {
        logger.info("<====== 进入placeOrder:方法,{[orders, goods, addressId] :" + addressId + " } ====");

        //获取用户默认收货地址
        Address address = null;
        if (addressId == 0l) {
            address = addressService.findUserDefaultAddress(orders.getUserId());
        } else {
            address = addressService.findOne(addressId);
        }

        if (null != orders && goods.size() != 0 && address != null) {
        	logger.info("<====== 进入placeOrder:方法,{[orders] :" + orders.toString() + " } ====");
            orders.setStatus(1);
            //默认类型线下支付
            if (orders.getPayType() == 0)
                orders.setPayType(2);
            orders.setName(address.getName());
            orders.setAddress(address.getAddressName());
            orders.setPhone(address.getPhone());
            orders.setWatch(false);
            orders.setCreatedBy(String.valueOf(orders.getUserId()));
            orders.setCreatedDate(new Date());
            orders.setLastModifiedDate(new Date());
            orders.setLastModifiedBy(orders.getUserId()+"");
            Orders order = ordersDao.save(orders);
            for(GoodsVo goodVo : goods) {
                if (goodVo.getNumber() < 0 ) {
                    logger.error("==== 提交的商品数量不合法 ====");
                    return false;
                }
                orderDetailService.addOrderDetailFromGoods(Long.valueOf(goodVo.getId()), order.getId(), goodVo.getNumber());
            }
            logger.info("==== 退出placeOrder方法 返回值类型:{ Boolean: true} =======>");
            return true;
        } else {
            if (null == address)
                logger.info("==== 用户Address为空 ====");
            if (goods.size() == 0)
                logger.info("==== 订单项不能为 ====>" + goods.size());
            logger.info("==== 退出placeOrder方法 返回值类型:{ Boolean: false} =======>");
            return false;
        }
    }

    @Override
    public Boolean refuseOrders(Long ordersId) {
        logger.info("<====== 进入refuseOrders:方法,{[ordersId] :" + ordersId + " } ====");
        Boolean result = false;
        Orders orders = ordersDao.findOne(ordersId);
        if (null != orders) {
            if (orders.getStatus() == 1 || orders.getStatus() == 2) {
                orders.setStatus(7);
                orders.setWatch(true);
                ordersDao.save(orders);
                result = true;
            } else {
                logger.info("==== 非法更改或者操作订单状态 ====");
            }
        } else {
            logger.info("==== 订单不存在 ====");
        }
        logger.info("==== 退出refuseOrders方法 返回值类型:{ Boolean:" + result + " } =======>");
        return result;
    }

    @Override
    public Boolean acceptOrders(Long ordersId) {
        logger.info("<====== 进入acceptOrders:方法,{[ordersId] :" + ordersId + " } ===");
        Boolean result = false;
        Orders orders = ordersDao.findOne(ordersId);
        if (null != orders) {
            if (orders.getStatus() == 2 || (orders.getStatus() == 1 && orders.getPayType() == 2)) { //已支付订单可以被接单，未支付订单，但是选择线下支付可以被接单
                orders.setStatus(3);
                orders.setWatch(true);
                ordersDao.save(orders);
                result = true;
            } else {
                logger.info("==== 非法更改或者操作订单状态 ====");
            }
        } else {
            logger.info("==== 订单不存在 ====");
        }
        logger.info("==== 退出acceptOrders方法 返回值类型:{ Boolean: " + result + "} =======>");
        return result;
    }

    @Override
    public Boolean rebackOrders(Long ordersId) {
        //TODO 退单
        logger.info("<====== 进入rebackOrders:方法,{[ordersId]:" + ordersId + " } ===");
        Boolean result = false;
        Orders orders = ordersDao.findOne(ordersId);
        if (null != orders) {
            if (orders.getStatus() == 1 || orders.getStatus() == 2 || orders.getStatus() == 3) {
                orders.setStatus(8);
                orders.setWatch(true);
                ordersDao.save(orders);
                result = true;
            } else {
                logger.error("==== 退单不成功 ====");
            }
        } else {
            logger.error("==== 订单不存在 ====");
        }
        logger.info("==== 退出rebackOrders方法 返回值类型:{ Boolean: " + result + " } =======>");
        return result;
    }

    @Override
    public Page<Orders> getAllOrders(Integer pageIndex, Integer size) {
        logger.info("<====== 进入getAllOrders:方法 [pageIndex: " +
                pageIndex + "],[size:" +
                size + "] ===");

        if (null == size || 0 == size)
            size = Comment.DEFAULT_SIZE;
        Pageable pageable = new PageRequest(pageIndex, size, new Sort(Sort.Direction.DESC, "id"));
        logger.info("==== 退出getAllOrders方法 返回值类型:{ List<Orders>: } =======>");
        return (Page<Orders>) ordersDao.findAll(pageable);
    }

    @Override
    public Boolean deliverOrders(Long orderId) {
        logger.info("<====== 进入deliverOrders:方法,{[orderId] :" + orderId + " } ====");
        Boolean result = changeOrderStatus(orderId, 4, 3);
        logger.info("==== 退出deliverOrders方法 返回值类型:{Boolean: " + result + "} =======>");
        return result;
    }

    @Override
    public Boolean doneOrders(Long orderId) {
        logger.info("<====== 进入doneOrders:方法,{[orderId] :" + orderId + " } ====");
        Boolean result = changeOrderStatus(orderId, 5, 4);
        logger.info("==== 退出doneOrders方法 返回值类型:{Boolean: " + result + "} =======>");
        return result;
    }

    @Override
    public Boolean commentOrders(Long orderId) {
        logger.info("<====== 进入commentOrders:方法,{[orderId] :" + orderId + " } ====");
        Boolean result = changeOrderStatus(orderId, 6, 5);
        logger.info("==== 退出commentOrders方法 返回值类型:{Boolean: " + result + "} =======>");
        return result;
    }

    @Override
    public List<Orders> findOrdersByStatus(Integer status) {
        logger.info("<====== 进入findOrdersByStatus:方法,{[status] :" +
                status + "}");

        logger.info("==== 退出findOrdersByStatus方法 返回值类型:{ Page<Orders>: } =======>");
        return ordersDao.findByStatus(status);
    }

    @Override
    public List<Orders> findUserAllOrders(Long userId) {
        logger.info("<====== 进入findUserAllOrders:方法,{[userId] :" + userId + " } ====");
        logger.info("==== 退出findUserAllOrders方法 返回值类型:{ Page<Orders>: } =======>");
        return ordersDao.findByUserIdAndIsDeleteFalse(userId);
    }

    @Override
    public List<OrderDetail> getOrdersInfo(Long ordersId) {

        logger.info("<====== 进入getOrdersInfo:方法,{[ordersId] :" + ordersId + " } ====");
        logger.info("==== 退出getOrdersInfo方法 返回值类型:{ List<OrderDetail>: } =======>");
        return orderDetailService.findOrdersDetail(ordersId);
    }

    /**
     * 更改订单状态
     * @param ordersId
     * @param status  设置当前状态
     * @param checkStatus 检查前面一个状态
     * @return
     */
    public Boolean changeOrderStatus(Long ordersId, int status,int checkStatus) {
        logger.info("<====== 进入changeOrderStatus:方法,{[ordersId, status, checkStatus] : } ====");
        Orders order = ordersDao.findOne(ordersId);
        if (null != order && order.getStatus() == checkStatus) {
            order.setStatus(status);
            ordersDao.save(order);
            logger.info("==== 退出changeOrderStatus方法 返回值类型:{ Boolean: true } =======>");
            return true;
        } else {
            logger.info("=== 该订单不存在,或者更改状态不合法 ===");
            new DomainSecurityException("该订单不存在,或者更改状态不合法");
            logger.info("==== 退出changeOrderStatus方法 返回值类型:{ Boolean: false } =======>");
            return false;
        }
    }

	@Override
	public List<Orders> findShopUnWatchOrder(Long shopperId) {
		return ordersDao.findByShopUserIdAndWatchFalseAndIsDeleteFalse(shopperId);
	}

	@Override
	public Charge payOrders(Long ordersId, String payWay) {
		Orders orders = ordersDao.findOne(ordersId);
		if (null == orders && orders.getStatus() != 1) {
		    logger.error("==== 订单不存在，或者订单状态修改不合法 ====");
            return null;
        }
		Charge charge = null;
        try {
            //TODO 添加order_no配对
            String orderId = "123456789" + orders.getId();
            String success_url = "http://127.0.0.1:8080/zhifuyemian/paySuccess.html?orderId=" + orders.getId();
//            String success_url = "http://localhost:8080/user";

            if (payWay.equals("wx") || payWay.equals("alipay")) {
                charge = PayChargeUtil.charge(orderId, (long) orders.getTotalPrice(), payWay,
                        orders.getName(),"没有说明",null);
            } else {
                charge = PayChargeUtil.charge(orderId, (long) orders.getTotalPrice(), payWay,
                        orders.getName(), "没有说明", success_url);
            }
        } catch (AuthenticationException e) {
            e.printStackTrace();
        } catch (InvalidRequestException e) {
            e.printStackTrace();
        } catch (APIConnectionException e) {
            e.printStackTrace();
        } catch (APIException e) {
            e.printStackTrace();
        } catch (ChannelException e) {
            e.printStackTrace();
        }
		logger.info("==== 退出payOrders方法 返回值类型:{ Charge:" + charge + "} =======>");
        return charge;
	}

    @Override
    public Boolean callBackPayOrders(Long orderId) {
        logger.info("<====== 进入callBackPayOrders:方法,{[orderId] :" + orderId +" } ====");
        Orders orders = ordersDao.findOne(orderId);
        Boolean result = false;
        if (null != orders && orders.getStatus() == 1) {
            orders.setStatus(2);
            //商家没查看
            orders.setWatch(false);
            ordersDao.save(orders);
            result = true;
        } else {
            logger.error("==== 订单不存在，或者订单状态不满足修改要求 =====");
        }
        logger.info("==== 退出callBackPayOrders方法 返回值类型:{ Boolean:" + result + " } =======>");
        return result;
    }

    @Override
	public List<Orders> findUserUnGetOrders(Long userId) {
		return ordersDao.findByUserIdAndStatusAndIsDeleteFalse(userId,4);
	}

	@Override
	public List<Orders> findUserUnCommentOrders(Long userId) {
		return ordersDao.findByUserIdAndStatusAndIsDeleteFalse(userId, 5);
	}

	@Override
	public Boolean userConfirmGetOrders(Long ordersId) {
		Orders findOne = ordersDao.findOne(ordersId);
		findOne.setStatus(5);
		findOne.setWatch(true);
		ordersDao.save(findOne);
		return true;
	}

	@Override
	public List<Orders> findShopUnSendOrder(Long shopperId) {
		return ordersDao.findByShopUserIdAndStatusAndIsDeleteFalse(shopperId,3);
	}

	@Override
	public List<Orders> userUnpayOrders(Long userId) {
		// TODO Auto-generated method stub
		return ordersDao.findByUserIdAndStatusAndIsDeleteFalse(userId, 1);
	}
}
